// test/err.go
// =============================================================================
// | 包: main                                                                |
// | 功能: 错误处理测试程序                                                  |
// | 说明: 演示两种不同的错误处理方法，包括使用pkg/errors包和runtime包        |
// =============================================================================
package main

import (
	"fmt"
	"runtime" // Go运行时库

	"github.com/pkg/errors" // 第三方错误处理包
)

// =============================================================================
// | 函数: main                                                              |
// | 功能: 程序入口，演示两种错误处理方法                                    |
// =============================================================================
func main() {
	// 创建一个基础错误
	err := errors.New("发生了一个错误")

	// 调用第一种错误处理方法（使用pkg/errors包）
	SetError1(err)

	// 调用第二种错误处理方法（使用runtime包）
	SetError(err)
}

// =============================================================================
// | 函数: SetError1                                                         |
// | 参数: @err - error (需要处理的错误对象)                                  |
// | 功能: 使用github.com/pkg/errors包进行错误处理                           |
// | 说明: 为错误添加堆栈信息并格式化输出                                    |
// =============================================================================
func SetError1(err error) {
	// 使用WithStack为错误添加堆栈信息
	msg := errors.WithStack(err)

	// 格式化输出错误详情和堆栈信息
	// %+v 会显示完整的错误链和调用堆栈
	fmt.Printf("方法一输出:\n%+v\n", msg)
}

// =============================================================================
// | 函数: SetError                                                          |
// | 参数: @err - error (需要处理的错误对象)                                  |
// | 功能: 使用runtime包手动获取堆栈信息                                     |
// | 说明: 获取当前goroutine的调用堆栈并输出                                 |
// =============================================================================
func SetError(err error) {
	// 创建一个1KB的缓冲区来存储堆栈信息
	var msg = make([]byte, 1024)

	// 获取当前goroutine的调用堆栈
	// 参数false表示不包含其他goroutine的信息
	n := runtime.Stack(msg, false)

	// 输出错误信息和调用堆栈
	fmt.Println("方法二输出:")
	fmt.Println("错误:", err)
	fmt.Println(string(msg[:n])) // 将字节切片转换为字符串输出
}
